Crate tugger_apple_codesign[][src]

Binary code signing for Apple platforms.

This crate provides a pure Rust implementation of binary code signing for Apple operating systems (like macOS and iOS). A goal of this crate is to facilitate reimplementing functionality from Apple’s codesign and other similar tools without a dependency on an Apple machine or operating system: you should be able to sign Apple binaries from Linux or Windows if you wanted to.

This crate is in its early stages of development and there are many rough edges. Use at your own risk. Always validate signed binaries with Apple’s codesign tool to ensure correctness.

Features and Capabilities

This crate can:

  • Find code signature data embedded in Mach-O binaries (both single and multi-arch/fat/universal binaries). (See AppleSignable trait and its methods.)
  • Deeply parse code signature data into Rust structs. (See EmbeddedSignature, BlobData, and e.g. CodeDirectoryBlob.
  • Parse and verify the RFC 5652 Cryptographic Message Syntax (CMS) signature data. This includes using a Time-Stamp Protocol (TSP) / RFC 3161 server for including a signed time-stamp token for that signature. (Functionality provided by the cryptographic-message-syntax crate, developed in the same repository as this crate.)
  • Generate new embedded signature data, including cryptographically signing that data using any signing key and X.509 certificate chain you provide. (See MachOSigner and BundleSigner.)
  • Writing a new Mach-O file containing new signature data. (See MachOSigner.)
  • Parse CodeResources XML plist files defining information on nested/signed resources within bundles. This includes parsing and applying the filtering rules defining in these files.
  • Sign bundles. Nested bundles will automatically be signed. Additional Mach-O binaries outside the main executable will also be signed. Non Mach-O/code files will be digested. A CodeResources XML file will be produced.

There are a number of missing features and capabilities from this crate that we hope are eventually implemented:

  • Only embedded signatures are supported. (No support for detached signatures.)
  • No parsing of the Code Signing Requirements DSL. We support parsing the binary requirements to Rust structs, serializing back to binary, and rendering to the human friendly DSL. You will need to use the csreq tool to compile an expression to binary and then give that binary blob to this crate. Alternatively, you can write Rust code to construct a code requirements expression and serialize that to binary.
  • No turnkey support for signing keys. We want to make it easier for obtaining signing keys (and their X.509 certificate chain) for use with this crate. It should be possible to easily integrate with the OS’s key store or hardware based stores (such as Yubikeys). We also don’t look for necessary X.509 certificate extensions that Apple’s verification likely mandates, which we should do and enforce.
  • Notarization support. The notarization ticket appears to be part of the embedded signature data. We don’t support parsing this blob. It should be possible to coerce this crate into emitting a notarization blob in the signature data. But this isn’t currently implemented as part of our high-level signing primitives.

There is missing features and functionality that will likely never be implemented:

  • Binary verification compliant with Apple’s operating systems. We are capable of verifying the digests of code and other embedded signature data. We can also verify that a cryptographic signature came from the annotated public key in that signature. We can also write heuristics to look for certain common problems with signatures. But we can’t and likely never will implement all the rules Apple uses to verify a binary for execution because we perceive there to be little value in doing this. This crate could be used to build such functionality elsewhere, however.

Getting Started

This crate is still in early phases of development. Until things are more mature, a good place to start with the source code is main.rs to get a feel for what CLI commands do.

The MachOSigner type is your gateway to how code signing is performed.

The AppleSignable trait extends the goblin::mach::MachO type with code signing functionality.

The EmbeddedSignature type describes existing code signatures on Mach-O binaries.

If you’d like to learn about the technical underpinnings of code signing on Apple platforms, see specification.

Accessing Apple Code Signing Certificates

This crate doesn’t yet support integrating with the macOS keychain to obtain or use the code signing certificate private key. However, it does support importing the certificate key from a .p12 file exported from the Keychain Access application. It also supports exporting the x509 certificate chain for a given certificate by speaking directly to the macOS keychain APIs.

See the keychain-export-certificate-chain CLI command for exporting a code signing certificate’s x509 chain as PEM.

Re-exports

pub use code_requirement::*;

Modules

code_requirement

Code requirement language primitives.

specification

Apple code signing technical specifications

Structs

BlobEntry

Represents a single blob as defined by a SuperBlob index entry.

BlobWrapperBlob

Represents a generic blob wrapper.

BundleSigner

A primitive for signing an Apple bundle.

CodeDirectoryBlob

Represents a code directory blob entry.

CodeResources

Represents a _CodeSignature/CodeResources XML plist.

CodeResourcesBuilder

Interface for constructing a CodeResources instance.

CodeResourcesRule

Represents an abstract rule in a CodeResources XML plist.

CodeSignatureFlags

Code signature flags.

DetachedSignatureBlob

A detached signature.

Digest
EmbeddedSignature

Represents embedded signature data in a Mach-O binary.

EmbeddedSignatureBlob

Represents an embedded signature.

EmbeddedSignatureOldBlob

An old embedded signature.

EntitlementsBlob

Represents an Entitlements blob.

ExecutableSegmentFlags

Flags that influence behavior of executable segment.

MachOSignatureData

Describes signature data embedded within a Mach-O binary.

MachOSigner

Mach-O binary signer.

OtherBlob

Represents an unknown blob type.

ParsedBlob

Represents the parsed content of a blob entry.

RequirementBlob

Represents a Requirement blob.

RequirementSetBlob

Represents a Requirement set blob.

Scatter
SignedMachOInfo

Metadata about a signed Mach-O file or bundle.

SigningSettings

Represents code signing settings.

SingleBundleSigner

A primitive for signing a single Apple bundle.

VerificationContext

Context for a verification issue.

VerificationProblem

Enums

AppleCodesignError

Unified error type for Apple code signing.

BlobData

Represents a single, parsed Blob entry/slot.

CertificateAuthorityExtension

Denotes specific certificate extensions on Apple certificate authority certificates.

CertificateProfile

Describes combinations of certificate extensions for Apple code signing certificates.

CodeDirectoryVersion

Version of Code Directory data structure.

CodeSigningCertificateExtension

Describes one of the many X.509 certificate extensions found on Apple code signing certificates.

CodeSigningMagic

Defines header magic for various payloads.

CodeSigningSlot

Defines a typed slot within code signing data.

DesignatedRequirementMode

Describes how to derive designated requirements during signing.

DigestType

Represents a digest type from a CS_HASHTYPE_* constants.

ExecutionPolicy

Defines well-known execution policies for signed code.

ExtendedKeyUsagePurpose

Describes the type of code signing that a certificate is authorized to perform.

KnownCertificate

Defines all known Apple certificates.

RequirementType

Denotes type of code requirements.

SettingsScope

Denotes the scope for a setting.

VerificationProblemType

Describes a problem with verification.

Constants

OID_USER_ID

UserID.

Traits

AppleCertificate

Extends functionality of CapturedX509Certificate with Apple specific certificate knowledge.

AppleCertificateBuilder

Extensions to X509CertificateBuilder specializing in Apple certificate behavior.

AppleSignable
Blob

Provides common features for a parsed blob type.

BundleFileHandler

Used to process individual files within a bundle.

Functions

compute_code_hashes

Compute code hashes for a Mach-O binary.

compute_paged_hashes

Compute paged hashes.

create_code_directory_hashes_plist

Obtain the XML plist containing code directory hashes.

create_self_signed_code_signing_certificate

Create a new self-signed X.509 certificate suitable for signing code.

create_superblob

Create the binary content for a SuperBlob.

derive_designated_requirements

Derive a designated requirements expression given a code signing certificate.

find_signature_data

Attempt to extract a reference to raw signature data in a Mach-O binary.

parse_pfx_data

Parse PFX data into a key pair.

verify_macho

Verifies a parsed Mach-O binary.

verify_macho_data

Verifies unparsed Mach-O data.

verify_path

Verifies a binary in a given path.